/**********************************************************************
 ** Copyright (C) 2009 Nokia Corporation.
 ** All rights reserved.
 **
 ** $LICENSE_TEXT$
 **********************************************************************/

#ifndef BTSERIALPORTCLIENT_H
#define BTSERIALPORTCLIENT_H

#include <QObject>

class QIODevice;
class QDBusMessage;
class QDBusPendingCallWatcher;

/**
 * @brief The BtSerialPortClient class configures a serial bluetooth connection.
 *
 * It uses Bluez D-Bus interface to bind a serial rfcomm device and provides a QIODevice to encapsulate
 * the communication with the device.
 */
class BtSerialPortClient: public QObject
{
    Q_OBJECT

public:

    /**
     * Constructs a BtSerialPortClient object with the given parent.
     *
     * @param parent Parent.
     */
    explicit BtSerialPortClient(QObject *parent = 0);

    /**
     * Destructs the BtSerialPortClient object.
     */
    ~BtSerialPortClient();

    /**
     * Disconnects bluetooth device.
     */
    void disconnect();

private:

    /**
     * Retrieves first argument from QDBusMessage and tries to extract the QDBusObjectPath.
     * @param message Return from D-Bus call.
     * @return QString with object path.
     */
    QString firstArgumentToObjectPath(QDBusMessage message);

    /**
     * Test if errorTest is an error and emits error() signal.
     * @param errorTest Boolean indicating if it is an error.
     * @return Boolean indicating if it is an error.
     */
    bool isError(bool errorTest);

    /**
     * Test if message is a QDBusMessage error and emits error() signal.
     * @param message QDBusMessage to be tested.
     * @return Boolean indicating if it is an error message.
     */
    bool isErrorMessage(QDBusMessage message);

signals:

    /**
     * Signal emitted after serial interface is bounded.
     */
    void interfaceBounded(QIODevice *serialPort);

    /**
     * Signal emitted after serial has been disconnected.
     */
    void disconnected();

    /**
     * Signal emitted when an error occurs.
     */
    void error();

private slots:

    /**
     * Tries to bind a serial connection device and emits an error() signal if unsuccessfull.
     */
    void setupInterface(QString address);

    /**
     * Called by D-Bus device connection observer when connection state changes.
     *
     * In case of disconnection, it disconnects the bluez serial device and emit the disconnected() signal.
     * @param message Connection status message.
     */
    void updateConnectionStatus(const QDBusMessage& message);

    /**
     * Called after async call to connect DBus method.
     * @param watcher Watcher to monitor DBus call.
     */
    void connectionCallFinishedSlot(QDBusPendingCallWatcher* watcher);

private:
    QString m_devicePath;
    bool m_isConnected;
};

#endif // BTSERIALPORTCLIENT_H
